XSS攻击
XSS 全称是 Cross Site Scripting,为了与“CSS”区分开来,故简称 XSS,翻译过来就是“跨站脚本”。XSS 攻击是指黑客往 HTML 文件中注入恶意脚本,从而在用户浏览页面时利用注入的恶意脚本对用户实施攻击的一种手段
通过恶意脚本的注入方式不同,可以将XSS攻击分为如下三类:
存储型XSS攻击
黑客利用站点漏洞将一段恶意 JavaScript 代码提交到网站的数据库中,然后用户向网站请求包含了恶意 JavaScript 脚本的页面;当用户浏览该页面的时候,恶意脚本就会将用户的 Cookie 信息等数据上传到服务器
如喜马拉雅的一个存储型XSS漏洞:
由于未对用户输入进行处理,所以恶意脚本被保存至数据库,当页面显示专辑名称时便会将恶意代码注入HTML运行
反射型XSS
其是指恶意脚本作为请求参数的一部分被发送到服务器(如http://localhost:3000/?xss=<script>...</script>),然后服务器将这段脚本返回给客户端(如将脚本通过后台渲染注入HTML),浏览器发现是JS脚本便运行了恶意代码
需要注意的是,Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击不同的地方
基于DOM的XSS攻击
这种方式的工作原理是在数据的传输过程中劫持数据并向HTML页面中注入恶意代码。该种方式不经过web服务器
上述介绍了三种不同的XSS攻击,那么下面就来谈谈如何阻止XSS攻击:
1、服务器对输入内容进行过滤或转码(不要相信任何输入)
如下述代码:
1 | 输入:<script>alert('你被xss攻击了')</script> |
2、为cookie设置HttpOnly(浏览器端措施)
通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的。如下:
1 | set-cookie: NID=......; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly |
使用 HttpOnly 标记的 Cookie 只能在浏览器发送 HTTP 请求时自动携带,而无法通过 JavaScript 来读取这段 Cookie。这样就能防止恶意脚本读取cookie
3、充分利用CSP(浏览器端措施)
实施严格的 CSP 可以有效地防范 XSS 攻击,具体来讲 CSP 有如下几个功能:
- 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的
- 禁止向第三方域提交数据,这样用户数据也不会外泄
- 禁止执行内联脚本和未授权的脚本
- 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题
CSRF攻击
CSRF 英文全称是 Cross-site request forgery,即“跨站请求伪造”
CSRF攻击的核心在于利用了浏览器的这个特性————用户访问某个站点时,浏览器会自动将它存储的该站点的cookie等信息添加到本次请求头中
基于上述特性,CSRF的攻击原理如下:如你登陆了A站点,黑客引诱你点击恶意链接到黑客站点的网页,黑客在该网页中构造了一条请求A站点某个接口(如转账接口)的HTTP请求,当浏览器打开黑客网页并发送HTTP请求,利用浏览器的上述特性便能伪造成是你在访问该接口
CSRF攻击的三种方式
1、自动发起GET请求
1 | <!DOCTYPE html> |
这是黑客页面的 HTML 代码,在这段代码中,黑客将转账的请求接口隐藏在 img 标签内,欺骗浏览器这是一张图片资源。当该页面被加载时,浏览器会自动发起 img 的资源请求。从而实现转账
2、自动发起 POST 请求
1 | <!DOCTYPE html> |
在这段代码中,我们可以看到黑客在他的页面中构建了一个隐藏的表单,该表单的内容就是极客时间的转账接口。当用户打开该站点之后,这个表单会被自动执行提交;当表单被提交之后,服务器就会执行转账操作
3、引诱用户点击链接
这种方式通常出现在论坛或者恶意邮件上。黑客会采用很多方式去诱惑用户点击黑客站点上的链接
1 | <div> |
这段黑客站点代码,页面上放了一张美女图片,下面放了图片下载地址,而这个下载地址实际上是黑客用来转账的接口,一旦用户点击了这个链接,那么他的钱就被转到黑客账户上了
防止CSRF攻击
1、利用好 Cookie 的 SameSite 属性
SameSite 选项通常有 Strict、Lax 和 None 三个值
Strict最为严格。如果SameSite的值是Strict,那么浏览器会完全禁止第三方 Cookie。即除非你在A站点内访问A站点的某个接口,如果你在第三方站点访问A站点的某个接口的话,浏览器是不会吧cookie等信息自动添加到请求头中的Lax相对宽松一点。在跨站点的情况下,从第三方站点的链接打开和从第三方站点提交 Get 方式的表单这两种方式都会携带 Cookie。但如果在第三方站点中使用 Post 方法,或者通过img、iframe等标签加载的 URL,这些场景都不会携带 Cookie- 而如果使用 None 的话,在任何情况下都会发送 Cookie 数据。默认值
1 | set-cookie: 1P_JAR=2019-10-20-06; expires=Tue, 19-Nov-2019 06:36:21 GMT; path=/; domain=.google.com; SameSite=none |
2、验证请求的来源站点
即在服务器端通过请求头中的Origin和Referrer字段来验证请求来源是否来自第三方站点
从上图可以看出,Origin 属性只包含了域名信息,并没有包含具体的 URL 路径,这是 Origin 和 Referer 的一个主要区别
但我们可通过Ajax中的自定义请求头来伪造这两个字段的值,因此此种方法安全性较差
3、CSRF Token
该种方式分为两部
第一步,在浏览器向服务器发起请求时,服务器生成一个 CSRF Token。CSRF Token 其实就是服务器生成的字符串,然后将该字符串植入到返回的页面中。你可以参考下面示例代码:
1 | <!DOCTYPE html> |
第二步,在浏览器端如果要发起请求,那么需要带上页面中的 CSRF Token,然后服务器会验证该 Token 是否合法。如果是从第三方站点发出的请求,那么将无法获取到 CSRF Token 的值,所以即使发出了请求,服务器也会因为 CSRF Token 不正确而拒绝请求
HTTPS
HTTPS产生的原因
由于HTTP采用的是明文传输,那么在数据的传输过程中便可能遭遇中间人攻击,如下:
具体来讲,在将 HTTP 数据提交给 TCP 层之后,数据会经过用户电脑、WiFi 路由器、运营商和目标服务器,在这中间的每个环节中,数据都有可能被窃取或篡改。比如用户电脑被黑客安装了恶意软件,那么恶意软件就能抓取和篡改所发出的 HTTP 请求的内容。或者用户一不小心连接上了 WiFi 钓鱼路由器,那么数据也都能被黑客抓取或篡改
HTTPS
HTTPS并不是一个新的协议。其只是在HTTP协议栈中加入了安全层。如下:
安全层有两个主要的职责:对发起 HTTP 请求的数据进行加密操作和对接收到 HTTP 的内容进行解密操作
下面我们便一步一步的构建HTTPS
第一版HTTPS——使用对称加密
所谓对称加密是指加密和解密都使用的是相同的密钥
由上图可知这一版本的HTTPS工作原理如下:
- 浏览器发送它所支持的加密套件列表和一个随机数 client-random,这里的加密套件是指加密的方法,加密套件列表就是指浏览器能支持多少种加密方法列表
- 服务器会从加密套件列表中选取一个加密套件,然后还会生成一个随机数 service-random,并将 service-random 和所选的加密套件列表返回给浏览器
- 至此,浏览器和服务器便都有了
service-random和client-random。然后他们利用这两个随机数生成密钥 - 然后浏览器便用生成的密钥加密数据,服务器收到数据后再用密钥解密
该种方式的问题在于:传输 client-random 和 service-random 的过程却是明文的,这意味着黑客也可以拿到协商的加密套件和双方的随机数,由于利用随机数合成密钥的算法是公开的,所以黑客拿到随机数之后,也可以合成密钥,这样数据依然可以被破解,那么黑客也就可以使用密钥来伪造或篡改数据了。为此我们继续改进得到第二版HTTPS
第二版HTTPS——使用非对称加密
非对称加密是指:非对称加密算法有 A、B 两把密钥,如果你用 A 密钥来加密,那么只能使用 B 密钥来解密;反过来,如果你要 B 密钥来加密,那么只能用 A 密钥来解密
由上图可知这一版本的HTTPS工作原理如下:
- 浏览器发送它所支持的加密套件列表到服务器
- 服务器返回它所选的加密套件和公钥(以明文的形式传输),私钥则留在服务器端
- 浏览器和服务器双方进行确认
- 之后浏览器便可以使用公钥加密数据了,而由于私钥在服务器端,所以只有服务器能用私钥解密数据
服务器自己留下的那个密钥称为私钥,只有服务器才能知道,不对任何人公开。明文的形式发送给浏览器的那个密钥被称为公钥
该种方式的问题在于:
- 非对称加密的效率太低。这会严重影响到加解密数据的速度,进而影响到用户打开页面的速度
- 无法保证服务器发送给浏览器的数据安全。由于浏览器使用的是公钥,因此服务器只能用私钥加密数据,这样浏览器才能用公钥解密。但是由于公钥是明文传输,因此黑客可以获取到,那么黑客就能解密服务端发给浏览器的数据
为此我们继续改进得到第三版HTTPS
第三版HTTPS——对称加密和非对称加密搭配使用
由上图可知这一版本的HTTPS工作原理如下:
- 首先浏览器向服务器发送对称加密套件列表、非对称加密套件列表和随机数 client-random
- 服务器保存随机数 client-random,选择对称加密和非对称加密的套件,然后生成随机数 service-random,向浏览器发送选择的对称和非对称加密套件、service-random 和公钥
- 浏览器保存公钥,并生成随机数 pre-master,然后利用公钥对 pre-master 加密,并向服务器发送加密后的数据。由于私钥仅有服务器才有,因此pre-master是不能被黑客破解的
- 最后服务器拿出自己的私钥,解密出 pre-master 数据,并返回确认消息
- 到此为止,服务器和浏览器就有了共同的 client-random、service-random 和 pre-master,然后服务器和浏览器会使用这三组随机数生成对称密钥master secret,因为服务器和浏览器使用同一套方法来生成密钥,所以最终生成的密钥也是相同的
- 有了对称加密的密钥之后,双方就可以使用对称加密的方式来传输数据了
不过这种方式依然存在着问题,比如我要打开极客时间的官网,但是黑客通过 DNS 劫持将极客时间官网的 IP 地址替换成了黑客的 IP 地址,这样我访问的其实是黑客的服务器了,黑客就可以在自己的服务器上实现公钥和私钥,而对浏览器来说,它完全不知道现在访问的是个黑客的站点
为此我们继续改进得到最终版HTTPS
最终版HTTPS——添加数字证书
对于浏览器来说,数字证书有两个作用:一个是通过数字证书向浏览器证明服务器的身份,以防DNS劫持;另一个是数字证书里面包含了服务器公钥
数字证书由权威机构 CA(Certificate Authority)颁发,并放于服务器端
由上图可知,相较于第三版HTTPS,最终版HTTPS仅多了数字证书验证。注意这儿公钥是包含在数字证书中的